package com.yuandian.customer.perception.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuandian.api.customer_perception.po.IndexParamsPo;
import com.yuandian.api.customer_perception.vo.*;
import com.yuandian.base.service.ITaskDataService;
import com.yuandian.bpm.common.core.util.R;
import com.yuandian.constant.Constants;
import com.yuandian.customer.perception.mapper.IndexMapper;
import com.yuandian.customer.perception.service.IIndexService;
import com.yuandian.enums.TableNameEnum;
import com.yuandian.utils.DataBelongUtil;
import com.yuandian.utils.PageDataInfo;
import com.yuandian.utils.YDateUtil;
import com.yuandian.vo.TrendDataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 说明：首页service实现
 *
 * @Author yanjun
 * @Date 2021/3/8 13:23
 */
@Slf4j
@Service
public class IndexServiceImpl implements IIndexService {

    @Autowired
    private IndexMapper indexMapper;

    @Autowired
    private ITaskDataService taskDataService;


    /**
     * 查询系统类型统计量topN
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> querySystemTypeTopNItem(IndexParamsPo params) {
        // 1、设置表名
		String tableName = TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName();
        params.setTableName(tableName);

        // 2、查询系统类型统计量topN
        List<IndexItemVo> list = indexMapper.querySystemTypeTopNItem(params);

        // 3、设置历史表名
        params.setTableName(TableNameEnum.ADS_BUSI_INDEX_ITEM_OVERVIEW.getName());
        list.forEach(vo -> {
            params.setSystemType(vo.getSystemType());
            // 查询历史峰值、历史平均值，填充数据
            IndexItemVo hisVo = indexMapper.queryHisSystemTypeItem(params);
            if (hisVo != null) {
                vo.setHisMax(hisVo.getHisMax());
                vo.setHisAvg(hisVo.getHisAvg());
            }
        });
        return R.ok(list);
    }

    /**
     * 询业务统计量topn(总数量降序前n个重点业务)
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusiTopNItem(IndexParamsPo params) {
        // 1、查询出所有重点业务
//		List<SearchOptionVo> optionList = searchOptionService.queryKeyBusinessBySystemId(params.getSystemId());	TODO 远程调用
		List<SearchOptionVo> optionList = new ArrayList<>();
        List<String> businessCodeList = optionList.stream().map(SearchOptionVo::getCode).collect(Collectors.toList());
        params.setBusinessCodeList(businessCodeList);

        // 2、查询总数量topN
		String tableName = TableNameEnum.MYSQL_BUSI_SYS_DETAIL_STAT_M.getName();
        params.setTableName(tableName);
        List<IndexItemVo> list = indexMapper.queryBusiTotalCountTopN(params);

        // 3、如果无数据也要展示业务名称
        if (CollectionUtils.isEmpty(list)) {
            list = new ArrayList<>();
            for (int i = 0; i < optionList.size(); i++) {
                if (i < 3) {
                    SearchOptionVo businessOption = optionList.get(i);
                    IndexItemVo vo = new IndexItemVo();
                    vo.setBusinessName(businessOption.getLabel());
                    vo.setBusinessCode(businessOption.getCode());
                    list.add(vo);
                }
            }
            return R.ok(list);
        }

        // 4、设置历史表名
        params.setTableName("ads_busi_index_item_overview");
        list.forEach(vo -> {
            params.setBusinessCode(vo.getBusinessCode());
            // 查询历史峰值、历史平均值，填充数据
            IndexItemVo hisVo = indexMapper.queryHisBusiItem(params);
            if (hisVo != null) {
                vo.setHisMax(hisVo.getHisMax());
                vo.setHisAvg(hisVo.getHisAvg());
            }
        });
        return R.ok(list);
    }

    /**
     * 首页项查询(总业务)(一条数据，如果查询出多条数据会报错)
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusiAllItem(IndexParamsPo params) {
        // 1、设置表名
        params.setTableName(TableNameEnum.ADS_BUSI_INDEX_ITEM_OVERVIEW.getName());
        // 2、查询历史峰值、历史平均值
        IndexItemVo vo = indexMapper.queryBusiAllItem(params);
        if (vo == null) {
            vo = new IndexItemVo();
            vo.setHisAvg(0);
            vo.setHisMax(0);
        }
        // 3、查询总数量
		String tableName = TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName();
        params.setTableName(tableName);
        IndexItemVo totalCountVo = indexMapper.queryBusiTotalCount(params);
        if (totalCountVo == null) {
            vo.setTotalCount(0);
        } else {
            vo.setTotalCount(totalCountVo.getTotalCount());
            vo.setFailRate(totalCountVo.getFailRate());
        }
        return R.ok(vo);
    }

    /**
     * 首页项查询(服务用户数)(一条数据，如果查询出多条数据会报错)
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryUserCountItem(IndexParamsPo params) {
        // 1、设置表名
        params.setTableName(TableNameEnum.ADS_BUSI_INDEX_ITEM_OVERVIEW.getName());
        // 2、查询历史峰值、历史平均值
        IndexItemVo vo = indexMapper.queryUserCountItem(params);
        if (vo == null) {
            vo = new IndexItemVo();
            vo.setHisAvg(0);
            vo.setHisMax(0);
        }
        // 3、查询总数量
		String tableName = TableNameEnum.ADS_BUSI_DETAIL_USER_STAT_M.getName();
        params.setTableName(tableName);
        IndexItemVo totalCountVo = indexMapper.queryUserTotalCount(params);
        if (totalCountVo == null) {
            vo.setTotalCount(0);
        } else {
            vo.setTotalCount(totalCountVo.getTotalCount());
        }
        return R.ok(vo);
    }

    /**
     * 根据系统类型查询首页项趋势
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryItemTrendBySystemType(IndexParamsPo params) {
        TrendDataVo trendDataVo = taskDataService.getTrendObject("KHGZ-详单分钟统计", params.getStartTime(), params.getEndTime(), null);
        if (trendDataVo.isLastShow()){
			params.setEndTime(YDateUtil.parseDateToStr(YDateUtil.YYYY_MM_DD_HH_MM_SS,new Date(DateUtil.parse(trendDataVo.getTrendEndTime(), YDateUtil.YYYY_MM_DD_HH_MM_SS).getTime()+60*1000)));
        }
        //将endTime倒推半小时得到endTimeAhead
        String endTimeAhead = YDateUtil.parseDateToStr(YDateUtil.YYYY_MM_DD_HH_MM_SS,new Date(DateUtil.parse(params.getEndTime(),YDateUtil.YYYY_MM_DD_HH_MM_SS).getTime()-30*60*1000));

        // 1、设置表名
        if (params.getTrendType() == 1) {
            // 设置开始时间
            params.setStartTime(DataBelongUtil.getMinCycleTime(endTimeAhead, 1));

			params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
        } else {
            // 天
            params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
            String startTimeStr = params.getStartTime();
            params.setStartTime(YDateUtil.getBeforeDayTime(startTimeStr, 11));
            params.setEndTime(startTimeStr);
        }
        // 2、执行查询
        List<IndexItemTrendVo> list = indexMapper.queryItemTrendBySystemType(params);
        // 3、计算时间标签
        if (params.getTrendType() == 1) {
            List<IndexItemTrendVo> result = new ArrayList<>();
            Map<String, List<IndexItemTrendVo>> map = DataBelongUtil
                    .dataBelong(endTimeAhead, 1, list, IndexItemTrendVo.class);
            map.forEach((labelTime, voList) -> {
                IndexItemTrendVo r = new IndexItemTrendVo();
                r.setCompleteCount(0);
                r.setVisitCount(0);
                voList.forEach(vo -> {
                    r.setCompleteCount(r.getCompleteCount() + vo.getCompleteCount());
                    r.setVisitCount(r.getVisitCount() + vo.getVisitCount());
                });
                r.setLabelTime(labelTime);
                result.add(r);
            });
            return R.ok(result);
        } else {
            List<IndexItemTrendVo> resList = DataBelongUtil
                    .dataBelongForTypeThree(params.getEndTime(), list, IndexItemTrendVo.class);
            return R.ok(resList);
        }
    }

    /**
     * 查询首页项趋势
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryItemTrend(IndexParamsPo params) {
        TrendDataVo trendDataVo = taskDataService.getTrendObject("KHGZ-详单分钟统计", params.getStartTime(), params.getEndTime(), null);
        if (trendDataVo.isLastShow()){
			params.setEndTime(YDateUtil.parseDateToStr(YDateUtil.YYYY_MM_DD_HH_MM_SS,new Date(DateUtil.parse(trendDataVo.getTrendEndTime(), YDateUtil.YYYY_MM_DD_HH_MM_SS).getTime()+60*1000)));
		}
        //将endTime倒推半小时得到endTimeAhead
		String endTimeAhead = YDateUtil.parseDateToStr(YDateUtil.YYYY_MM_DD_HH_MM_SS,new Date(DateUtil.parse(params.getEndTime(),YDateUtil.YYYY_MM_DD_HH_MM_SS).getTime()-30*60*1000));

		// 1、设置表名
        if (params.getTrendType() == 1) {
            // 设置开始时间
            params.setStartTime(DataBelongUtil.getMinCycleTime(endTimeAhead, 1));
			params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
        } else {
            // 天
			params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
			String startTimeStr = params.getStartTime();
			params.setStartTime(YDateUtil.getBeforeDayTime(startTimeStr, 11));
			params.setEndTime(startTimeStr);
        }
        // 2、执行查询
        List<IndexItemTrendVo> list = indexMapper.queryItemTrend(params);
        // 3、计算时间标签
        if (params.getTrendType() == 1) {
            List<IndexItemTrendVo> result = new ArrayList<>();
            Map<String, List<IndexItemTrendVo>> map = DataBelongUtil
                    .dataBelong(endTimeAhead, 1, list, IndexItemTrendVo.class);
            map.forEach((labelTime, voList) -> {
                IndexItemTrendVo r = new IndexItemTrendVo();
                r.setCompleteCount(0);
                r.setVisitCount(0);
                voList.forEach(vo -> {
                    r.setCompleteCount(r.getCompleteCount() + vo.getCompleteCount());
                    r.setVisitCount(r.getVisitCount() + vo.getVisitCount());
                });
                r.setLabelTime(labelTime);
                result.add(r);
            });
            return R.ok(result);
        } else {
            List<IndexItemTrendVo> resList = DataBelongUtil
                    .dataBelongForTypeThree(params.getEndTime(), list, IndexItemTrendVo.class);
            return R.ok(resList);
        }
    }

    /**
     * 查询地图区域业务量列表
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryAreaBusiList(IndexParamsPo params) {
        // 1、设置表名
        params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));
        // 2、执行查询
        List<AreaBusiVo> list = indexMapper.queryAreaBusiList(params);
//        AreaBusiVo res = indexMapper.queryAreaBusiDetail(params);
        return R.ok(list);
    }

    /**
     * 查询地图区域业务量列表
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryHallBusiList(IndexParamsPo params) {
        // 1、设置表名
        params.setTableNameList(Collections.singletonList(TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName()));

        // 查询所有的市区和市区编码
        List<CityBusiVo> areaList = indexMapper.queryAreaList(params);
        // 查询各营业厅的受理量
        List<HallBusiVo> hallList = indexMapper.queryHallBusiList(params);
        for (CityBusiVo area : areaList) {
            List<HallBusiVo> list = new ArrayList<>();
            for (HallBusiVo hall : hallList) {
                if (area.getAreaCode() != null && area.getAreaCode().equals(hall.getAreaCode())) {
                    list.add(hall);
                }
            }
            area.setHallBusiVoList(list);
        }

        return R.ok(areaList);
    }

    /**
     * 查询营业员活跃趋势
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryOperatorOnlineTrend(IndexParamsPo params) throws ParseException {
        //当type为1时，对开始时间进行处理，先将结束时间归并到00、15、30、45，再往前推5.5个小时作为开始时间
        if ("1".equals(params.getType())){
            int minute=YDateUtil.getMinute(new Date(params.getEndTime()));
            if (minute>=0&&minute<15){
                SimpleDateFormat sdf = new SimpleDateFormat(YDateUtil.YYYY_MM_DD_HH);
                params.setStartTime(YDateUtil.yyyy_MM_dd_HH_mm_ss(YDateUtil.getBeforeMinute(sdf.parse(params.getEndTime()),330)));
            }else if (minute>=15&&minute<30){
                SimpleDateFormat sdf = new SimpleDateFormat(YDateUtil.YYYY_MM_DD_HH);
                params.setStartTime(YDateUtil.yyyy_MM_dd_HH_mm_ss(YDateUtil.getBeforeMinute(sdf.parse(params.getEndTime()),315)));
            }else if (minute>=30&&minute<45){
                SimpleDateFormat sdf = new SimpleDateFormat(YDateUtil.YYYY_MM_DD_HH);
                params.setStartTime(YDateUtil.yyyy_MM_dd_HH_mm_ss(YDateUtil.getBeforeMinute(sdf.parse(params.getEndTime()),300)));
            }else{
                SimpleDateFormat sdf = new SimpleDateFormat(YDateUtil.YYYY_MM_DD_HH);
                params.setStartTime(YDateUtil.yyyy_MM_dd_HH_mm_ss(YDateUtil.getBeforeMinute(sdf.parse(params.getEndTime()),285)));
            }
        }
        //重设endTime
        TrendDataVo trendDataVo = taskDataService.getTrendObject("KHGZ-详单分钟统计", params.getStartTime(), params.getEndTime(), null);
        if (trendDataVo.isLastShow()){
			params.setEndTime(YDateUtil.parseDateToStr(YDateUtil.YYYY_MM_DD_HH_MM_SS,new Date(DateUtil.parse(trendDataVo.getTrendEndTime(), YDateUtil.YYYY_MM_DD_HH_MM_SS).getTime()+60*1000)));

		}
        // 1、设置表名(今日)
        String tableName = TableNameEnum.ADS_BUSI_SYS_VISIT_TREND_M.getName();
        params.setTableName(tableName);
        // 2、执行查询(今日)
        List<OperatorOnlineTrendVo> todayList = indexMapper.queryOperatorOnlineTrend(params);
        String startTime = params.getStartTime();
        String endTime = params.getEndTime();
        // 3、设置表名(昨日)
        String beforeStartTime = YDateUtil.getBeforeDayTime(params.getStartTime(), 1);
        String beforeEndTime = YDateUtil.getBeforeDayTime(params.getEndTime(), 1);
        params.setStartTime(beforeStartTime);
        params.setEndTime(beforeEndTime);
        // 4、执行查询(昨日)
        List<OperatorOnlineTrendVo> yesterdayList = indexMapper.queryOperatorOnlineTrend(params);
        // 5、合并数据
        Map<String, OperatorOnlineTrendVo> collect = yesterdayList
                .stream()
                .collect(Collectors.toMap(OperatorOnlineTrendVo::getCycleTime, v -> v, (k1, k2) -> k1));
        List<OperatorOnlineTrendVo> list = new ArrayList<>();
        todayList.forEach(today -> {
            OperatorOnlineTrendVo vo = new OperatorOnlineTrendVo();
            String cycleTime = today.getCycleTime();
            vo.setCycleTime(cycleTime);
            vo.setTodayCount(today.getOperatorCount());
//            Date cycleTimeDate = YDateUtil.yyyy_MM_dd_HH_mm_ss(cycleTime);
//            cycleTime = YDateUtil.yyyy_MM_dd_HH_mm_ss(YDateUtil.getBeforeDate(cycleTimeDate, 1));
            if (collect.containsKey(cycleTime)) {

                vo.setYesterdayCount(collect.get(cycleTime).getOperatorCount());
            } else {
                vo.setYesterdayCount(0);
            }
            list.add(vo);
        });

        HashMap<String,List<Object>> resultMap=new HashMap<>();
        List<Object> todayCycleTimeList=new ArrayList<>();
        List<Object> todayDataList=new ArrayList<>();
        List<Object> yesterDayDataList=new ArrayList<>();
        list.forEach(operatorOnlineTrendVo -> {
            todayCycleTimeList.add(operatorOnlineTrendVo.getCycleTime());
            todayDataList.add(operatorOnlineTrendVo.getTodayCount());
            yesterDayDataList.add(operatorOnlineTrendVo.getYesterdayCount());
        });

        resultMap.put("todayCycleTimeList",todayCycleTimeList);
        resultMap.put("todayDataList",todayDataList);
        resultMap.put("yesterDayDataList",yesterDayDataList);
        trendDataVo.setTrendData(resultMap);

        return R.ok(trendDataVo);
    }

    /**
     * 查询营业员活跃趋势跨天
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryOperatorOnlineTrendCrossDay(IndexParamsPo params) throws ParseException {
        // 1、获取表信息集

        // 3、设置表名、时间范围矫正
        params.setTableNameList(Collections.singletonList(TableNameEnum.KHGZ_BUSI_SYS_DETAIL_STAT.getName()));

        List<OperatorOnlineTrendVo> list = indexMapper.queryOperatorOnlineTrendCrossDay(params);

        HashMap<String,List<Object>> resultMap=new HashMap<>();
        List<Object> todayCycleTimeList=new ArrayList<>();
        List<Object> todayDataList=new ArrayList<>();
        list.forEach(operatorOnlineTrendVo -> {
            todayCycleTimeList.add(operatorOnlineTrendVo.getCycleTime());
            todayDataList.add(operatorOnlineTrendVo.getTodayCount());
        });

        resultMap.put("todayCycleTimeList",todayCycleTimeList);
        resultMap.put("todayDataList",todayDataList);

        // 3、处理时间标签
        TrendDataVo trendDataVo = taskDataService.getTrendObject("KHGZ-详单分钟统计", params.getStartTime(), params.getEndTime(), resultMap);
        return R.ok(trendDataVo);
    }

    /**
     * 查询业务告警类型
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusiAlarmType(IndexParamsPo params) {
        // 设置表名
        params.setTableName(TableNameEnum.ADS_BUSI_ALARM_TREND_M.getName());
        // 执行查询
        List<BusiAlarmTypeVo> list = indexMapper.queryBusiAlarmType(params);
        return R.ok(list);
    }

    /**
     * 查询告警业务统计数
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusiAlarmStatisCount(IndexParamsPo params) {
        BusiAlarmStatisCountVo vo = new BusiAlarmStatisCountVo();

		// 指定查询'首端'告警数据
		params.setHeaderFlag(1);

		// 总数
		vo.setTotalCount(indexMapper.queryBusiAlarmStatisCount(params));

        // 紧急
		params.setAlarmLevel(4);
 		vo.setUrgentCount(indexMapper.queryBusiAlarmStatisCount(params));

        // 重大
		params.setAlarmLevel(3);
		vo.setImportantCount(indexMapper.queryBusiAlarmStatisCount(params));

        return R.ok(vo);
    }

    /**
     * 查询告警业务TopN
     *
     * @param params 首页请求对象
     * @return 通用返回对象
     */
    @Override
    public R<Object> queryBusiAlarmTopN(IndexParamsPo params) {
        Page<BusiAlarmTopNVo> page = new Page<>(params.getPageNum(), params.getPageSize());
        // 设置表名
        params.setTableName(TableNameEnum.ADS_BUSI_ALARM_TREND_M.getName());
        // 执行查询
        List<BusiAlarmTopNVo> allData = indexMapper.queryBusiAlarmList(params);
        List<BusiAlarmTopNVo> list = indexMapper.queryBusiAlarmTopN(page, params);
        if (allData != null) {
			for (BusiAlarmTopNVo busiAlarmTopNVo : list) {
                for (int i = 0; i < allData.size(); i++) {
                    BusiAlarmTopNVo b = allData.get(i);
                    // 为返回前端的结果集添加排名rank
                    if (busiAlarmTopNVo.getSystemId() == b.getSystemId()
                            && Objects.equals(busiAlarmTopNVo.getBusinessCode(), b.getBusinessCode())) {
                        busiAlarmTopNVo.setRank(i + 1);
                        break;
                    }
                }
            }
        }
        return R.ok(new PageDataInfo(page, list != null ? list : new ArrayList<BusiAlarmTopNVo>()));
    }
}
